import { CanActivate, ExecutionContext, Inject, Injectable, UnauthorizedException } from '@nestjs/common';
import { UserService } from './user/user.service';
import { Request } from 'express';
import { Permission } from './user/entities/perssion.entity';
import { Reflector } from '@nestjs/core';


@Injectable()
export class PermissionGuard implements CanActivate {

    // 注入 userService
    @Inject(UserService)
    private userService:UserService

    @Inject()
    private reflector: Reflector;


    async canActivate(
        context: ExecutionContext,
    ):  Promise<boolean> {
        const request: Request = context.switchToHttp().getRequest();

        if(!request.user) {
          return true;
        }
        
        // 获取 用户token中的roles
        const roles = await this.userService.findRolesById(request.user.roles as number[])
        // 查出 roles 的 permission 信息，然后合并到一个数组里
        const permissions: Permission[]  = roles.reduce((total, current) => {
            total.push(...current.permissions);
            return total;
        }, []);

        
        
        const requiredPermissions = this.reflector.getAllAndOverride<string[]>('require-permission', [
            context.getClass(),
            context.getHandler()
        ])
        
        // 为了方便测试 没有配置角色权限的一律通过  生产环境应该是false
        if(!requiredPermissions){
            return true
        }
        
        // 对比 用户 token中的 路由 是否含有该权限
        requiredPermissions.forEach(per =>{
            const flag = permissions.find(item => item.name === per);
            if(!flag) {
                throw new UnauthorizedException('您没有访问该接口的权限');
            }
        })
          

        return true;
    }
}
